package com.fh.shop.api.cart.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fh.shop.api.cart.vo.CartItemVo;
import com.fh.shop.api.cart.vo.CartVo;
import com.fh.shop.api.common.ResponseEnum;
import com.fh.shop.api.common.ServerResponse;
import com.fh.shop.api.common.SystemConst;
import com.fh.shop.api.product.mapper.IProductMapper;
import com.fh.shop.api.product.po.Product;
import com.fh.shop.api.util.BigDecimalUtil;
import com.fh.shop.api.util.KeyUtil;
import com.fh.shop.api.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service("cartService")
public class ICartServiceImpl implements ICartService {
    @Autowired
    private IProductMapper productMapper;

    @Override
    public ServerResponse addCartItem(Long productId, Long count, Long memberId) {
        if (count.longValue() == 0) {
            return ServerResponse.error(ResponseEnum.CART_PRODUCT_COUNT_IS_ERROR);
        }
        // 商品是否存在
        Product product = productMapper.selectById(productId);
        if (product == null) {
            return ServerResponse.error(ResponseEnum.CART_PRODUCT_IS_NULL);
        }
        // 商品状态是否正常[下架]
        Integer status = product.getStatus();
        if (status.intValue() == SystemConst.PRODUCT_STATUS_DOWN) {
            return ServerResponse.error(ResponseEnum.CART_PRODUCT_STATUS_IS_DOWN);
        }
        // 商品的库存是否充足[库存量是否大于等于购买的数量]
        Integer stock = product.getStock();
        if (stock.intValue() < count) {
            return ServerResponse.error(ResponseEnum.CART_PRODUCT_STOCK_IS_ERROR);
        }
        String key = KeyUtil.buildCartKey(memberId);
//        String cartJson = RedisUtil.get(key);
        String cartJson = RedisUtil.hget(key, SystemConst.CART_CONENT);
        if (cartJson == null) {
            // 如果没有购物车，则创建购物车,向购物车中添加商品
            if (count < 0) {
                return ServerResponse.error(ResponseEnum.CART_PRODUCT_COUNT_IS_ERROR);
            }
            // 创建空的购物车
            CartVo cartVo = new CartVo();
            // 创建购车商品
            CartItemVo cartItemVo = buildCartItemVo(count, product);
            // 将商品加入了购物车并重新计算购物车的总价格，总数量
            cartVo.getCartItemVoList().add(cartItemVo);
            cartVo.setTotalCount(count);
            cartVo.setTotalPrice(cartItemVo.getSubTotal());
            // 购物车存到redis
            String cartVoJson = JSON.toJSONString(cartVo);
//            RedisUtil.set(key, cartVoJson);
//            RedisUtil.hset(key, SystemConst.CART_CONENT, cartVoJson);
//            RedisUtil.hset(key, SystemConst.CART_TOTAL, cartVo.getTotalCount()+"");
            updateRedisCart(key, cartVo, cartVoJson);
        } else {
            // 如果有购物车,判断购物车中是否已经有这个商品了
            CartVo cartVo = JSON.parseObject(cartJson, CartVo.class);
            Optional<CartItemVo> optionalCartItemVo = cartVo.getCartItemVoList().stream()
                                                            .filter(x -> x.getProductId().longValue() == productId.longValue())
                                                            .findFirst();
            if (optionalCartItemVo.isPresent()) {
                // 如果购物车中有对应的商品，更改了商品的数量,商品的小计
                CartItemVo cartItemVo = optionalCartItemVo.get();
                long newCount = cartItemVo.getCount() + count;
                if (newCount <= 0) {
                    // 要在购物车中删除这个商品
                    cartVo.getCartItemVoList().removeIf(x -> x.getProductId().longValue() == cartItemVo.getProductId().longValue());
                    if (cartVo.getCartItemVoList().size() == 0) {
                        // 删除整个购物车
                        RedisUtil.delete(key);
                        return ServerResponse.success();
                    }
                    updateCart(key, cartVo);
                    return ServerResponse.success();
                }
                cartItemVo.setCount(newCount);
                String price = cartItemVo.getPrice();
                BigDecimal subTotal = BigDecimalUtil.mul(price, newCount + "");
                cartItemVo.setSubTotal(subTotal.toString());
                updateCart(key, cartVo);
            } else {
                // 如果购物车中没有对应的商品
                if (count < 0) {
                    return ServerResponse.error(ResponseEnum.CART_PRODUCT_COUNT_IS_ERROR);
                }
                // 创建购车商品,向购物车中添加商品
                CartItemVo cartItemVo = buildCartItemVo(count, product);
                cartVo.getCartItemVoList().add(cartItemVo);
                //更新购物车
                // 遍历购物车中所有的商品，重新计算总价格，总数量
                updateCart(key, cartVo);
            }
        }
        return ServerResponse.success();
    }

    @Override
    public ServerResponse deleteById(Long id, Long memberId) {
        //=========验证【最后再去进行和数据库相关的验证】
        String key = KeyUtil.buildCartKey(memberId);
//        String cartJson = RedisUtil.get(key);
        String cartJson = RedisUtil.hget(key, SystemConst.CART_CONENT);
        if (cartJson == null) {
            return ServerResponse.error(ResponseEnum.CART_IS_NULL);
        }
        //=========逻辑
        CartVo cartVo = JSONObject.parseObject(cartJson, CartVo.class);
        List<CartItemVo> cartItemVoList = cartVo.getCartItemVoList();
        long count = cartItemVoList.stream().filter(x -> x.getProductId().longValue() == id.longValue()).count();
        if (count == 0) {
            return ServerResponse.error(ResponseEnum.CART_PRODUCT_ID_IS_ERROR);
        }
        cartItemVoList.removeIf(x -> x.getProductId().longValue() == id.longValue());
        if (cartItemVoList.size() == 0) {
            // 删除整个购物车
            RedisUtil.delete(key);
            return ServerResponse.success();
        }
        // 更新购物车
        updateCart(key, cartVo);
        return ServerResponse.success();
    }

    @Override
    public ServerResponse deleteBatch(String ids, Long memberId) {
        if (StringUtils.isNotEmpty(ids)) {
            //=========验证【最后再去进行和数据库相关的验证】
            String key = KeyUtil.buildCartKey(memberId);
//            String cartJson = RedisUtil.get(key);
            String cartJson = RedisUtil.hget(key, SystemConst.CART_CONENT);
            if (cartJson == null) {
                return ServerResponse.error(ResponseEnum.CART_IS_NULL);
            }
            //=========逻辑 1,88888,3
            String[] idArr = ids.split(",");
            CartVo cartVo = JSONObject.parseObject(cartJson, CartVo.class);
            List<CartItemVo> cartItemVoList = cartVo.getCartItemVoList();
            // for循环，删除
            Arrays.stream(idArr).forEach(x -> {
//                long count = cartItemVoList.stream().filter(y -> y.getProductId().longValue() == Long.parseLong(x)).count();
//                if (count == 1) {
                    cartItemVoList.removeIf(z -> z.getProductId().longValue() == Long.parseLong(x));
//                }
            });
            if (cartItemVoList.size() == 0) {
                // 删除整个购物车
                RedisUtil.delete(key);
            } else {
                // 更新购物车
                updateCart(key, cartVo);
            }
        }
        return ServerResponse.success();
    }

    @Override
    public ServerResponse findCartItemCount(Long memberId) {
        String key = KeyUtil.buildCartKey(memberId);
//            String cartJson = RedisUtil.get(key);
        boolean exist = RedisUtil.exist(key);
        if (!exist) {
            return ServerResponse.error(ResponseEnum.CART_IS_NULL);
        }
        String count = RedisUtil.hget(key, SystemConst.CART_TOTAL);
        return ServerResponse.success(count);
    }

    private void updateCart(String key, CartVo cartVo) {
        // 更新购物车
        // 遍历购物车中所有的商品，重新计算总价格，总数量
        long totalCount = 0;
        BigDecimal totalPrice = new BigDecimal(0);
        for (CartItemVo itemVo : cartVo.getCartItemVoList()) {
            totalCount += itemVo.getCount();
            totalPrice = totalPrice.add(new BigDecimal(itemVo.getSubTotal()));
        }
        cartVo.setTotalPrice(totalPrice.toString());
        cartVo.setTotalCount(totalCount);
        // 更新redis中的数据
        String cartVoJson = JSON.toJSONString(cartVo);
        // 更新redis中的hash里面的 content以及total
        updateRedisCart(key, cartVo, cartVoJson);
    }

    private void updateRedisCart(String key, CartVo cartVo, String cartVoJson) {
        Map<String, String> map = new HashMap<>();
        map.put(SystemConst.CART_CONENT, cartVoJson);
        map.put(SystemConst.CART_TOTAL, cartVo.getTotalCount() + "");
        RedisUtil.hmset(key, map);
    }

    private CartItemVo buildCartItemVo(Long count, Product product) {
        CartItemVo cartItemVo = new CartItemVo();
        cartItemVo.setProductId(product.getId());
        cartItemVo.setCount(count);
        cartItemVo.setProductName(product.getProductName());
        cartItemVo.setImage(product.getMainImage());
        String price = product.getPrice().toString();
        cartItemVo.setPrice(price);
        BigDecimal subTotal = BigDecimalUtil.mul(price, count + "");
        cartItemVo.setSubTotal(subTotal.toString());
        return cartItemVo;
    }
}
